﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using DevExpress.XtraEditors.ScrollHelpers;

namespace NewerthBot
{
    public partial class InstantMessage : Form
    {
        ScrollBarAPIHelper scroll;
        string FullUsername;
        string Username;

        #region Scrollbar
        [DllImport("User32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage")]
        static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("User32.dll", EntryPoint = "GetScrollPos")]
        static extern int GetScrollPos(IntPtr hWnd, int nBar);

        const int WM_VSCROLL = 0x115;
        const int SB_BOTTOM = 7;
        const int SB_VERT = 1;
        #endregion

        public InstantMessage(string _Username)
        {
            InitializeComponent();

            scroll = new ScrollBarAPIHelper();
            scroll.Init(txtChat, this);
            scroll.UpdateScrollBars();
            FullUsername = _Username;

            if (_Username.Contains("]"))
            {
                Username = _Username.Substring(_Username.IndexOf(']') + 1, _Username.Length - _Username.IndexOf(']') - 1);
            }
            else
            {
                Username = _Username;
            }

            Program.Core.onInstantMessage += new LibBot.Core.InstantMessageEventHandler(Core_onInstantMessage);
            Program.Core.onSendInstantMessage += new LibBot.Core.SendInstantMessageEventHandler(Core_onSendInstantMessage);
        }

        void Core_onSendInstantMessage(object sender, LibBot.SendInstantMessageEventArgs e)
        {
            if (e.Username == FullUsername)
            {
                this.Invoke(new EventHandler(
                    delegate
                    {
                        txtChat.AppendText(Environment.NewLine);
                        txtChat.AppendText("^770[" + DateTime.Now.ToShortTimeString() + "] ^444" + Program.Username + ": ^999" + e.Message);
                    }));
            }
        }

        void Core_onInstantMessage(object sender, LibBot.InstantMessageEventArgs e)
        {
            if (e.Username == FullUsername)
            {
                this.Invoke(new EventHandler(
                    delegate
                    {
                        txtChat.AppendText(Environment.NewLine);
                        txtChat.AppendText("^770[" + DateTime.Now.ToShortTimeString() + "] ^444" + e.Username + ": ^999" + e.Message);
                    }));
            }
        }

        private void btnSendMessage_Click(object sender, EventArgs e)
        {
            Program.Core.SendInstantMessage(Username, txtSendMessage.Text);
            txtSendMessage.Text = "";
        }

        private void txtSendChat_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter && btnSendMessage.Enabled)
            {
                e.SuppressKeyPress = true;
                Program.Core.SendInstantMessage(Username, txtSendMessage.Text);
                txtSendMessage.Text = "";
            }
        }

        private void txtSendMessage_TextChanged(object sender, EventArgs e)
        {
            if (txtSendMessage.Text != "")
            {
                btnSendMessage.Enabled = true;
            }
            else
            {
                btnSendMessage.Enabled = false;
            }
        }

        private void txtChat_VScroll(object sender, EventArgs e)
        {
            scroll.VScroll.Value = GetScrollPos(txtChat.Handle, SB_VERT);
        }

        private void txtChat_TextChanged(object sender, EventArgs e)
        {
            if (txtChat.Text != "")
            {
                string[] lines = txtChat.Lines;
                string originalmessage = lines[lines.Length - 1];
                string message = lines[lines.Length - 1];

                int r = 0;
                int g = 0;
                int b = 0;
                string pattern = @"\^\d{3}";
                string badpattern = @"\^\d{3}\^\d{3}";
                Match match;

                // Replace text colors with RGB colors
                message = message.Replace("^w", "^999");
                message = message.Replace("^r", "^900");
                message = message.Replace("^g", "^090");
                message = message.Replace("^b", "^009");
                message = message.Replace("^c", "^099");
                message = message.Replace("^y", "^990");
                message = message.Replace("^m", "^909");
                message = message.Replace("^v", "^444");
                message = message.Replace("^!b", "^029");
                message = message.Replace("^!t", "^176");
                message = message.Replace("^!p", "^304");
                message = message.Replace("^!o", "^851");
                message = message.Replace("^!i", "^836");
                message = message.Replace("^!v", "^555");
                message = message.Replace("^!g", "^032");
                message = message.Replace("^!n", "^310");

                // Uppercase
                message = message.Replace("^W", "^999");
                message = message.Replace("^R", "^900");
                message = message.Replace("^G", "^090");
                message = message.Replace("^B", "^009");
                message = message.Replace("^C", "^099");
                message = message.Replace("^Y", "^990");
                message = message.Replace("^M", "^909");
                message = message.Replace("^V", "^444");
                message = message.Replace("^!B", "^029");
                message = message.Replace("^!T", "^176");
                message = message.Replace("^!P", "^304");
                message = message.Replace("^!O", "^851");
                message = message.Replace("^!I", "^836");
                message = message.Replace("^!V", "^555");
                message = message.Replace("^!G", "^032");
                message = message.Replace("^!N", "^310");

                match = Regex.Match(message, badpattern);

                while (match.Success)
                {
                    message = message.Remove(message.IndexOf(match.Value), 4);
                    match = match.NextMatch();
                }

                match = Regex.Match(message, pattern);

                if (match.Success)
                {
                    if (message.StartsWith(match.Value))
                    {
                        foreach (string text in Regex.Split(message, pattern))
                        {
                            if (text != "")
                            {
                                if (match.Value != "")
                                {

                                    r = Convert.ToInt32(match.Value[1].ToString()) * (255 / 9);
                                    g = Convert.ToInt32(match.Value[2].ToString()) * (255 / 9);
                                    b = Convert.ToInt32(match.Value[3].ToString()) * (255 / 9);
                                }

                                txtChat.SelectionColor = Color.FromArgb(r, g, b);
                                txtChat.TextChanged -= txtChat_TextChanged;
                                txtChat.AppendText(text);
                                txtChat.TextChanged += txtChat_TextChanged;

                                match = match.NextMatch();
                            }
                        }
                    }
                    else
                    {
                        foreach (string text in Regex.Split(message, pattern))
                        {
                            if (text != "")
                            {
                                txtChat.SelectionColor = Color.FromArgb(r, g, b);
                                txtChat.TextChanged -= txtChat_TextChanged;
                                txtChat.AppendText(text);
                                txtChat.TextChanged += txtChat_TextChanged;

                                if (match.Value != "")
                                {
                                    r = Convert.ToInt32(match.Value[1].ToString()) * (255 / 9);
                                    g = Convert.ToInt32(match.Value[2].ToString()) * (255 / 9);
                                    b = Convert.ToInt32(match.Value[3].ToString()) * (255 / 9);
                                }

                                match = match.NextMatch();
                            }
                        }
                    }

                    txtChat.TextChanged -= txtChat_TextChanged;
                    txtChat.Rtf = txtChat.Rtf.Remove(txtChat.Rtf.LastIndexOf(originalmessage), originalmessage.Length);
                    txtChat.TextChanged += txtChat_TextChanged;
                }
                else
                {
                    txtChat.SelectionColor = Color.White;
                    txtChat.TextChanged -= txtChat_TextChanged;
                    txtChat.AppendText(message);
                    txtChat.TextChanged += txtChat_TextChanged;
                }
            }

            IntPtr ptrWparam = new IntPtr(SB_BOTTOM);
            IntPtr ptrLparam = new IntPtr(0);
            SendMessage(txtChat.Handle, WM_VSCROLL, ptrWparam, ptrLparam);
        }
    }
}
